#pragma once
#include "ast.h"
#include <iostream>
#include <string>
#include <unordered_map>
#include <vector>

class CodeGenerator {
    //唯一标签
    int labelCounter = 0;
    std::string CreateLabel();
    
    //处理控制流，记录循环上下文
    struct LoopContext {
        std::string startLabel;
        std::string endLabel;
    };
    
    //记录函数作用域内的状态
    struct Record {
        //管理栈帧、变量作用域
        std::unordered_map<std::string, int> varMap;
        int currentOffset = 0;

        //函数管理
        std::string exitLabel; //当前函数退出点标签
        int frameSize = 0;     //函数栈帧大小

        //控制流管理
        std::vector<LoopContext> loopStack;//循环上下文栈
        //进入新循环
        void pushLoop(const LoopContext& ctx) {
            loopStack.push_back(ctx);
        }
        //退出当前循环
        void popLoop() {
            if (!loopStack.empty()) {
                loopStack.pop_back();
            }
        }
        // 获取当前循环的起始标签
        std::string currentStartLabel() const {
            return loopStack.empty() ? "" : loopStack.back().startLabel;
        }
        // 获取当前循环的结束标签
        std::string currentEndLabel() const {
            return loopStack.empty() ? "" : loopStack.back().endLabel;
        }


        //管理寄存器资源
        std::vector<std::string> freeRegs;
        std::vector<std::string> usedRegs;
        std::vector<std::string> callerSaved;
        //初始化可用寄存器
        Record() {
            for (int i = 0; i < 7; i++) freeRegs.push_back("t" + std::to_string(i));//临时
            for (int i = 0; i < 8; i++) freeRegs.push_back("a" + std::to_string(i));//参数
        }
        //分配、释放寄存器
        std::string allocReg();
        void freeReg(const std::string& reg);
    };
           
        
    //代码生成
    std::string genExpr(std::ostream& os, Record& r, Expr* expr);
    void genStmt(std::ostream& os, Record& r, Stmt* stmt);
    void genFunc(std::ostream& os, FuncDef* func);
    
public:
    void Entrance(std::ostream& os, CompUnit* cu);
};